package com.shuwei.wificollecttool.recognize;

import com.shuwei.location.wificollect.WifiItem;
import com.shuwei.wificollecttool.recognize.dao.FingerPrintDao;
import com.shuwei.wificollecttool.recognize.dao.IFingerPrintDao;

import java.util.ArrayList;
import java.util.List;

public class FindFingerPrint {

    /**
     * for test
     * @param args
     */
    public static void main(String[] args) {
        FindFingerPrint findFingerPrint = new FindFingerPrint();
        String[] test_AP = {"50:fa:84:48:95:66", "d0:ee:07:1d:84:2c", "d0:ee:07:3f:17:6e", "8c:a6:df:c8:f3:ca", "b0:d5:9d:81:e5:41", "50:fa:84:48:95:68", "d4:ee:07:3f:17:6e", "d4:ee:07:1d:84:2c", "34:96:72:6c:2d:86", "90:b6:86:b8:32:cf", "88:25:93:bd:ef:8b", "50:fa:84:48:8b:1c", "38:e2:dd:22:41:b0", "8c:c7:d0:0b:f2:11", "a8:ad:3d:2c:a4:7c", "28:6c:07:96:77:55", "cc:79:cf:c0:6c:0a", "fc:37:2b:62:26:c9", "e0:10:7f:13:f4:b8", "50:fa:84:48:8b:1a", "06:1b:b1:22:88:40", "06:02:b4:49:aa:49", "d6:ee:07:3e:72:49", "d6:ee:07:37:32:1d", "2e:b2:1a:df:b3:10", "00:5a:13:18:c3:b6", "e0:10:7f:53:f4:b8", "8c:a6:df:c8:f3:cc", "96:53:30:70:79:bd"
        };
        int[] test_RSSI = {-39, -64, -63, -53, -45, -47, -58, -54, -55, -68, -47, -58, -55, -53, -62, -68, -54, -66, -69, -60, -77, -78, -46, -52, -72, -64, -72, -54, -76};
        List<WifiItem> currWifiItemList = new ArrayList<>();
        for (int i = 0; i < test_AP.length; i++) {
            WifiItem wifiItem = new WifiItem();
            String mac = test_AP[i];
            int rssi = test_RSSI[i];
            wifiItem.setRssi(rssi);
            wifiItem.setBssid(mac);
            currWifiItemList.add(wifiItem);
        }
        findFingerPrint.locationHit(currWifiItemList);
    }

    public void locationHit(List<WifiItem> currWifiItemList) {
        if (currWifiItemList==null || currWifiItemList.size() <=0) {
            return;
        }
        IFingerPrintDao iFingerPrintDao = new FingerPrintDao();
        List<List<WifiItem>> lists = iFingerPrintDao.queryAllFingerPrint();
        final int currSize = currWifiItemList.size();
        int x, y;
        int eachDbDataSize = lists.size();
        List<Double> pro1 = new ArrayList<>();
        List<Double> distance = new ArrayList<>();
        List<Integer> flag = new ArrayList<>();
        for (int i = 0; i < eachDbDataSize; i++) {
            flag.clear();
            List<WifiItem> wifiItems = lists.get(i);
            int eachDbDataSonSize = wifiItems.size();

            List<Double> sum_2 = new ArrayList<>();
            List<Double> diff_value_text2figer = new ArrayList<>();

            for (int j = 0; j < eachDbDataSonSize; j++) {
                for (int k = 0; k < currSize; k++) {
                    WifiItem currWifiItem = currWifiItemList.get(k);
                    WifiItem dbWifiItem = lists.get(i).get(j);
                    String currMac = currWifiItem.getBssid();
                    String dbMac = dbWifiItem.getBssid();
                    if (dbMac.equals(currMac)) {
                        int val = currWifiItem.getRssi() - dbWifiItem.getRssi();
                        double valPow = Math.pow(val, 2);
                        sum_2.add(new Double(valPow));
                        flag.add(j);
                        diff_value_text2figer.add(new Double(Math.abs(val)));
                    }
//                    break;
                }
            }
            double sum = sum(diff_value_text2figer);
            int diff_value_text2figer_size = diff_value_text2figer.size();

            double v = sum / diff_value_text2figer_size;
            distance.add(new Double(v));
            double pro = 0;
            double p = 0;
            for (int q = 0; q < diff_value_text2figer_size; q++) {
                Double item = diff_value_text2figer.get(q);
                if (item.doubleValue() < 6) {
                    p = 0.7;
                } else if (item.doubleValue() < 10 && item.doubleValue() > 6) {
                    p = 0.2;
                } else {
                    p = 0.1;
                }
                pro = pro + p;
                System.out.println(pro);
                System.out.println(p);
            }
            double v1 = pro / diff_value_text2figer_size;
            pro1.add(v1);
        }
        int maxIndex = getMaxIndex(pro1);
        int minIndex = 0;
        double minValue = distance.get(minIndex).doubleValue();
        for (int i = 1; i < distance.size(); i++) {
            double val = distance.get(i).doubleValue();
            if (minValue > val) {
                minIndex = i;
                minValue = val;
            }
        }
        int result = 0;
        for (int i = 0; i < flag.size(); i++) {
            int val = flag.get(i).intValue();
            if (val == maxIndex) {
                result = i;
                break;
            }
            if (i == (flag.size() - 1)) {
                if (this.locationListener != null) {
                    this.locationListener.locationNotHit(0, "not hit");
                }
            }
        }
        if (this.locationListener != null) {
            this.locationListener.locationHit(result, "hit");
        }
    }

    private int getMaxIndex(List<Double> pro1) {
        int maxIndex = 0;
        double maxValue = pro1.get(maxIndex).doubleValue();
        for (int i = 1; i < pro1.size(); i++) {
            double val = pro1.get(i).doubleValue();
            if (maxValue < val) {
                maxIndex = i;
                maxValue = val;
            }
        }
        return maxIndex;
    }

    private double sum(List<Double> list) {
        if (list == null || list.size() <= 0) {
            return 0;
        }
        double sum = 0;
        for (int i = 0; i < list.size(); i++) {
            Double item = list.get(i);
            sum += item.doubleValue();
        }
        return sum;
    }

    private LocationListener locationListener;

    public void setLocationListener(LocationListener locationListener) {
        this.locationListener = locationListener;
    }

    public interface LocationListener {

        /**
         * 没有传入信号
         */
        int NOT_HIT_CODE_EMPTY_SIGNALS = 0;
        /**
         * 确实没有匹配到
         */
        int NOT_HIT_CODE_NOT_HIT = 1;

        void locationHit(int x, String msg);

        /**
         *
         * @param notHitCode
         *          从{@link LocationListener#NOT_HIT_CODE_EMPTY_SIGNALS}
         *          和{@link LocationListener#NOT_HIT_CODE_NOT_HIT}
         *          中挑选
         * @param msg
         */
        void locationNotHit(int notHitCode, String msg);
    }
}
